var MongoConn = require("./lib/Connection.js");
var MongoQuery = require("./lib/query.js").Query;

var query = new MongoQuery();

var privilege = {
    safetyMode: false,
    add: true,
    read: true,
    update: true,
    remove: true,
    createCollection: true,
    deleteCollection: true
};

/**
 * create the connection by configuration
 *
 * @param config is different part to localhost:27017/test
 * @api public
 */
var EasyMongo = function (config) {
    if (!config)
        MongoConn({}, null);
    else
        MongoConn(config, null);
};

EasyMongo.prototype.exit = function(){
    MongoConn.exitConnections();
}

/**
 * add a BSON data record to db
 *
 * @param collectionName,BSON Data,Function to callback
 * @callback function(err,_id)
 * @api public
 */
EasyMongo.prototype.add = function (collectionName, object, callback) {
    if (privilege.add) {
        query.add(collectionName, object, callback);
    } else {
        callback({"msg": "no privilege to add"}, null);
    }
};

/**
 * update a BSON data record
 *
 * @param collectionName,where condition,update attributes,Function to callback
 * @callback function(err,_id)
 * @api public
 */
EasyMongo.prototype.update = function (collectionName, condition, object, callback) {
    if (privilege.update) {
        query.update(collectionName, condition, object, callback);
    } else {
        callback({"msg": "no privilege to update"}, null);
    }
};

/**
 * find a record by condition, filter by option
 *
 * @param collectionName,where condition,filter option [ pluck,order] ,Function to callback
 * @callback function(err,docs)
 * @api public
 */
EasyMongo.prototype.find = function (collectionName, condition, option, callback) {
    if (privilege.read) {
        if (arguments.length == 3) {
            query.find(collectionName, condition, {}, option);
        } else {
            query.find(collectionName, condition, option, callback);
        }
    } else {
        callback({"msg": "no privilege to find"}, null);
    }
};

/**
 * delete a BSON data record
 *
 * @param collectionName,where condition,update,Function to callback
 * @callback function(err)
 * @api public
 */
EasyMongo.prototype.remove = function (collectionName, condition, callback) {
    if (privilege.remove) {
        query.delete(collectionName, condition, callback);
    } else {
        callback({"msg": "no privilege to remove"}, null);
    }
};

/**
 * list all collections in current DB
 *
 * @param Function to callback
 * @callback function(err,collectionListArray)
 * @api public
 */
EasyMongo.prototype.listCollections = function (callback) {
    if (privilege.read) {
        MongoConn(function (err, db) {
            if (err)
                callback(err, null);
            else {
                db.listCollections({}).toArray(function (err, names) {
                    if(err) callback(err,null);
                    else callback(err, names);
                })
            }
        });
    } else {
        callback({"msg": "no privilege to read"}, null);
    }
};

/**
 * delete a collection by name
 *
 * @param collection name to delete ,Function to callback
 * @callback function(err,result)
 * @api public
 */
EasyMongo.prototype.removeCollection = function (name, callback) {
    if (privilege.deleteCollection) {
        MongoConn(function (err, db) {
            if (err)
                callback(err, null);
            else {
                db.dropCollection(name, function (err, result) {
                    if(err) callback(err,null);
                    else callback(err, result);
                });
            }
        });
    } else {
        callback({"msg": "no privilege to delete collection"}, null);
    }
};

//todo further ORM, maintain data structure
//EasyMongo.prototype.createCollection = function(collectionName,structure,callback) {
//    MongoQuery.createCollection(collectionName,structure,callback);
//};

//todo for restful interface
var createCollection = function (req, res) {
    res.send("createCollection");
};

var add = function (req, res) {
    res.send("add");
};

var read = function (req, res) {
    res.send("read");
};

var update = function (req, res) {
    res.send("update");
};

var remove = function (req, res) {
    res.send("remove");
};

var generateToken = function (req, res) {
    //todo for safetyMode
    res.send("token");
};

/**
 * express router for register restful API
 *
 * POST: /rest   body data: {collection: name, structure: {column: type}}
 * GET: /rest/collection   query: {where: condition object, option: option object}
 * POST: /rest/collection   body data: {column: value}
 * PUT: /rest/collection   body data: {where: condition, option: object, update: {column: value}}
 * DELETE: /rest/collection   body data: {where: condition, option: object}
 * Safety Option:
 * HEAD: Mongo API Server: set-cookie [random token + RSA salt] (First HEAD REQ, each session will encrypt in cookie)
 * REQ: /rest URL/salt+token+SHA1  Mongo: Decode  =  cookie token + salt + SHA1  set-cookie next
 *
 * @param express app variable
 * @callback function(err,_id)
 * @api public
 */
exports.registerMongoRestApi = function (app) {
    app.head('/rest', generateToken);
    app.post('/rest', createCollection);
    app.post('/rest/:collection', add);
    app.get('/rest/:collection', read);
    app.put('/rest/:collection', update);
    app.delete('/rest/:collection', remove);
};

exports.option = privilege;
exports.EasyMongo = EasyMongo;